﻿using System.Collections;
using System.Reflection;
using System.Text;
using System.Web.Mvc;
using Microsoft.Reporting.WebForms;

namespace EmbeddedReport.Web.Helpers
{
    public static class ReportViewerHelper
    {
        public static string RenderReport(this HtmlHelper helper, string ReportPath, object Model)
        {
            var reportType = "HTML4.0";

            var localReport = new LocalReport { ReportPath = ReportPath };
            localReport.EnableFormat(reportType);

            //Give the collection a name (EmployeeCollection) so that we can reference it in our report designer
            var reportDataSource = new ReportDataSource("NiceData", Model);
            localReport.DataSources.Add(reportDataSource);

            string mimeType;
            string encoding;
            string fileNameExtension;

            //The DeviceInfo settings should be changed based on the reportType
            //http://msdn2.microsoft.com/en-us/library/ms155397.aspx
            var deviceInfo = "<DeviceInfo><HTMLFragment>True</HTMLFragment> </DeviceInfo>"  ;

            Warning[] warnings;
            string[] streams;

            //Render the report
            var renderedBytes = localReport.Render(
                reportType,
                deviceInfo,
                out mimeType,
                out encoding,
                out fileNameExtension,
                out streams,
                out warnings);


            return Encoding.UTF8.GetString(renderedBytes); 

        }

        //http://beaucrawford.net/post/Enable-HTML-in-ReportViewer-LocalReport.aspx
        internal static void EnableFormat(this LocalReport localReport, string formatName)
        {
            const BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;

            var m_previewService = localReport.GetType().GetField
                (
                "m_previewService",
                Flags
                );


            var ListRenderingExtensions = m_previewService.FieldType.GetMethod
                (
                "ListRenderingExtensions",
                Flags
                );

            var previewServiceInstance = m_previewService.GetValue(localReport);

            var extensions = ListRenderingExtensions.Invoke(previewServiceInstance, null) as IList;

            var name = extensions[0].GetType().GetProperty("Name", Flags);

            foreach (var extension in extensions)
            {
                if (string.Compare(name.GetValue(extension, null).ToString(), formatName, true) == 0)
                {
                    var m_isVisible = extension.GetType().GetField("m_isVisible",
                                                                   BindingFlags.NonPublic | BindingFlags.Instance);

                    var m_isExposedExternally = extension.GetType().GetField("m_isExposedExternally",
                                                                             BindingFlags.NonPublic |
                                                                             BindingFlags.Instance);
                    m_isVisible.SetValue(extension, true);

                    m_isExposedExternally.SetValue(extension, true);

                    break;
                }
            }
        }

    }
}
